package com.assistant.hanleTask;

import com.assistant.utils.CommonComponent;
import com.assistant.xmlParse.XmlParser;
import javax.swing.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import static com.assistant.utils.CommonDefault.getPlatformBASeparator;
import static com.assistant.utils.CommonDefault.getPlatformSeparator;

public class MakeLogApk implements Runnable {
    private JTextField source;
    private JTextField target;
    private JPanel mjPanel;
    private JProgressBar jProgressBar;
    //判断是否成功注入日志，该方法主要是为了能够判断启动的 Activity 是否包含 onCreate 方法，如果没有该方法，就会导致日志注入不成功
    private boolean flag=false;
    public MakeLogApk(JTextField source, JPanel mjPanel, JProgressBar jProgressBar) {
        this.source = source;
        this.target = source;
        this.mjPanel = mjPanel;
        this.jProgressBar = jProgressBar;
    }
    @Override
    public void run() {
        //一键打包,采取默认的形式，通过要打包的apk
        //未完待续。。。
        if (source.getText().isEmpty()) {
            HandleCommand.handleTextFieldIsEmpty(mjPanel,"源路径不能为空！！");
        }
        //.apk
        String sourcePath = source.getText();
        File filename = new File(sourcePath);
        //目录
        String targetPath = target.getText().substring(0, target.getText().lastIndexOf(getPlatformSeparator()));
        //日志文件
        File logFile = new File(targetPath + getPlatformSeparator() + "log.txt");
        File apktool = new File("apktool.jar");
        File signedJKS = new File("feihu1.jks");
        HandleCommand.logFileIsExist(logFile);

        FileOutputStream logWriter = null;
        try {
            logWriter = new FileOutputStream(logFile);
            if (!apktool.exists()) {
                logWriter.write("can't find apktool.jar,please put it in the peer directory \n".getBytes());
                return;
            }
            if (!signedJKS.exists()) {
                logWriter.write("can't find the Signature file，please put it in the peer directory\n".getBytes());
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //反编译apk文件夹
        String decodeTargetPath = target.getText().substring(0, target.getText().lastIndexOf("."));
        String cmdDecode = "java -jar apktool.jar d " + sourcePath + " -o " + decodeTargetPath;
        //需要处理
        String cmdCompile = "java -jar apktool.jar b " + decodeTargetPath;
        //需要处理
        String cmdSigned = "jarsigner -verbose -keystore feihu1.jks " +
                "-signedjar " + decodeTargetPath + getPlatformSeparator() + "dist" + getPlatformSeparator() + "game_signed.apk -storepass 123qwe " + decodeTargetPath + getPlatformSeparator() + "dist" + getPlatformSeparator() + filename.getName() + " key0";
        String content = null;
        //处理工作都完成了
        HandleCommand.setjProgressValue(jProgressBar,10);
        try {
            logWriter.write("Preparatory work completed\n".getBytes());
            //反编译
            content = HandleCommand.handleCommandForMakeLogApk(cmdDecode, logWriter);
            HandleCommand.setjProgressValue(jProgressBar,30);
            logWriter.write("insert log statement\n".getBytes());
            //插入一条语句
            String relativePath = HandleCommand.parseXml(decodeTargetPath);
            injectSdkLog(relativePath, logWriter);
            HandleCommand.setjProgressValue(jProgressBar,50);

            if(!flag){
                CommonComponent.warningAlert(mjPanel,"警告","日志打包失败，找不到 onCreate() 方法！");
                HandleCommand.setjProgressValue(jProgressBar,100);
                return;
            }
            logWriter.write("start repackage... \n".getBytes());
            //反打包
            content += HandleCommand.handleCommandForMakeLogApk(cmdCompile, logWriter);
            HandleCommand.setjProgressValue(jProgressBar,70);
            logWriter.write("start signing... \n".getBytes());
            //签名
            content += HandleCommand.handleCommandForMakeLogApk(cmdSigned, logWriter);
            HandleCommand.setjProgressValue(jProgressBar,90);
            logWriter.write(content.getBytes());
            logWriter.close();
        } catch (IOException e) {
            System.out.println("io exception");
            e.printStackTrace();
        }
        HandleCommand.setjProgressValue(jProgressBar,100);

//      CommonComponent.warningAlert(jPanel,"操作成功", "操作完成");
    }


    //注入日志
    private void injectSdkLog(String relativePath, FileOutputStream logWriter) {
        try {
            String logContent = null;
            String targetPath = target.getText().substring(0, target.getText().lastIndexOf("."));
            if (!HandleCommand.checkIsSDKApk(targetPath)) {
                CommonComponent.warningAlert(mjPanel, "警告", "该apk不是盾包，请换一个尝试!");
                HandleCommand.setjProgressValue(jProgressBar,100);
                return;
            }
            if (!checkIsLogApk(targetPath)) {
                CommonComponent.warningAlert(mjPanel, "警告", "该包已经是日志包了，不需要再打了");
                HandleCommand.setjProgressValue(jProgressBar,100);
                return;
            }
            File targetFile = new File(targetPath + getPlatformBASeparator("smali") + relativePath + ".smali");
            //获取文件名
            String targetFileName = targetFile.getName();
            logContent = "get target file name :" + targetFileName + "\n";
            logWriter.write(logContent.getBytes());
            FileReader fileReader = new FileReader(targetFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            //需要生成的文件
            File generateFile = new File(targetPath + getPlatformBASeparator("smali") + targetFileName);
            FileWriter fileWriter = new FileWriter(generateFile);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
            String line;
            StringBuilder content = new StringBuilder();
            while ((line = bufferedReader.readLine()) != null) {
                if (line.trim().contains(".method protected onCreate(Landroid/os/Bundle;)V")) {
                    logWriter.write("find the launch activity's onCreate method\n".getBytes());
                    for (int i = 0; i < 10; i++) {
                        logWriter.write("now skip 10 line and will add log statement...\n".getBytes());
                        content.append(line + "\n");
                        line = bufferedReader.readLine();
                    }

                    content.append(line+"\n");
                    content.append("invoke-static {},Lcom/Qsu;->Log()V\n");
                    flag=true;
                    logWriter.write("success add the statement 'invoke-static {},Lcom/Qsu;->Log()V'\n".getBytes());
                } else {
                    content.append(line + "\n");
                }
            }
            logWriter.write("now close the launch activity's io stream\n".getBytes());
            bufferedReader.close();
            bufferedWriter.write(content.toString());
            bufferedWriter.flush();
            bufferedWriter.close();
            if (targetFile.delete()) {
                logContent = "delete successful the targetFile:" + targetFile.getName() + " and the file generated is renameTo targetFile..." + "\n";
                logWriter.write(logContent.getBytes());
                generateFile.renameTo(targetFile);
            }
        } catch (IOException e) {
            try {
                logWriter.write("ERROR! there is a ioException ,you should check it!".getBytes());
                logWriter.flush();

            } catch (IOException ex) {
                ex.printStackTrace();
                try {
                    logWriter.close();
                } catch (IOException exc) {
                    exc.printStackTrace();
                }
            }
            e.printStackTrace();
        }
    }
    private boolean checkIsLogApk(String targetPath) {
        //SearchFile searchFile=new SearchFile(targetPath,"Qsu;->");
        return true;
    }



}
